package com.doctor.database.dao;

import javax.persistence.PersistenceContext;

import java.io.Serializable;  
import java.util.LinkedHashMap;  
import java.util.List;  
import java.util.Map;  
  


import javax.persistence.EntityManager;  

import org.springframework.data.domain.Page;  
import org.springframework.data.domain.Pageable;  
import org.springframework.data.jpa.domain.Specification;  
import org.springframework.data.jpa.repository.support.JpaEntityInformation;  
import org.springframework.data.jpa.repository.support.JpaEntityInformationSupport;  
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;  
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional; 

@Repository("baseDao")
public class BaseDao{
	
    @PersistenceContext  
    private EntityManager em;  
    
    private static int MAX_CACHE_SIEZ = 200;  
    Map<Class<?>, SimpleJpaRepository> cache = new CacheHashMap();  
      
    /** 
     * 保存实体 
     * @param entity--要保存的实体 
     * @param entityClass--要保存的类型 
     * @return 保存后的实体 
     */ 
    @Transactional
    public <T> T save(T entity, Class<T> entityClass) {  
        JpaEntityInformation<T, ?> entityInfomation = JpaEntityInformationSupport.getMetadata(entityClass, em);  
        if(entityInfomation.isNew(entity)) {  
            em.persist(entity);  
            return entity;  
        } else {  
            T t = em.merge(entity);  
            return t;  
        }  
    }  
    /** 
     * 根据id删除实体 
     * @param id 
     * @param entityClass 
     */  
    @Transactional  
    public <T, ID extends Serializable> void delete(ID id, Class<T> entityClass) {  
        this.getRepository(entityClass).delete(id);  
    }  
    /** 
     * 根据id查询一个实体 
     * @param id 
     * @param entityClass 
     * @return 
     */  
    public <T, ID extends Serializable> T findOne(ID id, Class<T> entityClass) {  
        return this.getRepository(entityClass).findOne(id);  
    }  
    /** 
     * 查询所有实体 
     * @param entityClass 
     * @return 
     */  
    public <T> Iterable<T> findAll(Class<T> entityClass) {  
        return this.getRepository(entityClass).findAll();  
    }  
    /** 
     * 分页查询 
     * @param request 
     * @param entityClass 
     * @return 
     */  
    public <T> Page<T> getPage(Pageable request, Class<T> entityClass) {  
        return this.getRepository(entityClass).findAll(request);  
    }  
      
    /** 
     * 条件查询 
     * @param spec 
     * @param entityClass 
     * @return 
     */  
    public <T> List<T> findAll(Specification<T> spec, Class<T> entityClass) {  
        return this.getRepository(entityClass).findAll(spec);  
    }  
    /** 
     * 分页条件查询 
     * @param request 
     * @param spec 
     * @param entityClass 
     * @return 
     */  
    public <T> Page<T> getPageByFilter(Pageable request, Specification<T> spec, Class<T> entityClass) {  
        return this.getRepository(entityClass).findAll(spec, request);  
    }  
      
    /** 
     * 获取repository 
     * @param entityClass 
     * @return 
     */  
    private <T, ID extends Serializable> SimpleJpaRepository<T, ID> getRepository(Class<T> entityClass) {  
        if(cache.containsKey(entityClass)) {  
            return cache.get(entityClass);  
        }  
        SimpleJpaRepository<T, ID> repository = new SimpleJpaRepository<T, ID>(JpaEntityInformationSupport.getMetadata(entityClass, em), em);  
        cache.put(entityClass, repository);  
        return repository;  
    }  
    /** 
     * 缓存 
     * @author ppt 
     */  
    @SuppressWarnings("serial")  
    private static class CacheHashMap extends LinkedHashMap<Class<?>, SimpleJpaRepository>{  
        @Override  
        protected boolean removeEldestEntry(Map.Entry eldest) {  
            return size() > MAX_CACHE_SIEZ;  
        }  
    }  

}
